home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / ov143b.zip / MENU.C < prev    next >
C/C++ Source or Header  |  1993-01-04  |  9KB  |  245 lines

  1. /*  009  20-Apr-87  menu.c
  2.  
  3.         Copyright (c) 1987 by Blue Sky Software.  All rights reserved.
  4. */
  5.  
  6. #include <stdio.h>
  7. #include "menu.h"
  8. #include "direct.h"
  9.  
  10. #ifndef TRUE
  11. #define TRUE  (1)
  12. #define FALSE (0)
  13. #endif
  14.  
  15. /*  Following 4 items must be initialized by routines calling menu functions  */
  16.  
  17. int menu_row;                  /* tells menu rtns where to put menu on screen */
  18. MENU *top_menu;                /* top level menu pointer                      */
  19. int menu_hilite, menu_lolite;  /* video attributes to use for menu highlights */
  20.  
  21. MENU_STATE curmenu;            /* current state is avail 2 those who know how */
  22.  
  23. static MENU *save_top;                 /* local data */
  24. static MENU_STATE savmenu;
  25. static int force_selection = FALSE;
  26.  
  27.  
  28. /******************************************************************************
  29.  **                      M E N U _ D I S P L A Y                             **
  30.  *****************************************************************************/
  31.  
  32. static void ALTCALL
  33. menu_display(menu)     /* display a menu */
  34. register MENU *menu;
  35. {
  36.    int col = 0;
  37.    register int i;
  38.  
  39.    gotorc(menu_row,0);
  40.  
  41.    /* display each of the menu selections, for each one, remember where it
  42.       is on the menu row and how long it is.  This info is used by the
  43.       menu_select/deselect functions.  The end of the menu is denoted by
  44.       a set of NULL entries,  finished when this entry is found.  Put the
  45.       number of selections for this menu into the global variable
  46.       number_selections for other routines to use */
  47.  
  48.    for (i = 0; menu->choice != NULL; i++, menu++) {
  49.       curmenu.selection[i].position = col;
  50.       curmenu.selection[i].length = strlen(menu->choice);
  51.       disp_str(menu->choice);
  52.       disp_str("  ");
  53.       col += curmenu.selection[i].length + 2;
  54.    }
  55.  
  56.    clr_eol();
  57.  
  58.    curmenu.number_selections = i;      /* remember how many selections in menu */
  59. }
  60.  
  61.  
  62. /******************************************************************************
  63.  **                      M E N U _ S E L E C T                               **
  64.  *****************************************************************************/
  65.  
  66. static void ALTCALL
  67. menu_select(sel)       /* select (highlight) a menu selection */
  68. register int sel;
  69. {
  70.    setvattrib(menu_hilite);            /* set selection attribute */
  71.  
  72.    /* display the selection with attribute set */
  73.  
  74.    disp_str_at(curmenu.current_menu[sel].choice,menu_row,
  75.                curmenu.selection[sel].position);
  76.  
  77.    setvattrib(menu_lolite);            /* return to normal attribute */
  78. }
  79.  
  80.  
  81. /******************************************************************************
  82.  **                      M E N U _ P R O M P T                               **
  83.  *****************************************************************************/
  84.  
  85. static void ALTCALL
  86. menu_prompt(sel)       /* display a selection's prompt string */
  87. int sel;
  88. {
  89.    disp_str_at(curmenu.current_menu[sel].prompt,menu_row+1,0);
  90.    clr_eol();
  91. }
  92.  
  93.  
  94. /******************************************************************************
  95.  **                      M E N U _ D E S E L E C T                           **
  96.  *****************************************************************************/
  97.  
  98. static void ALTCALL
  99. menu_deselect(sel)     /* deselect (unhighlight) a menu selection */
  100. register int sel;
  101. {
  102.    /* display the selection with normal attribute */
  103.  
  104.    disp_str_at(curmenu.current_menu[sel].choice,menu_row,
  105.                curmenu.selection[sel].position);
  106. }
  107.  
  108.  
  109. /******************************************************************************
  110.                       M E N U _ S A V E / R E S T O R E
  111.  ******************************************************************************/
  112.  
  113. void ALTCALL
  114. menu_save() {          /* save the current menu state */
  115.  
  116.    savmenu = curmenu;
  117.    save_top = top_menu;
  118. }
  119.  
  120. void ALTCALL
  121. menu_restore() {       /* restore saved menu state */
  122.  
  123.    curmenu = savmenu;
  124.    top_menu = save_top;
  125.    force_selection = TRUE;
  126. }
  127.  
  128.  
  129. /******************************************************************************
  130.  **                       M E N U _ I N I T                                  **
  131.  *****************************************************************************/
  132.  
  133. void ALTCALL
  134. menu_init() {          /* initialize the menu */
  135.  
  136.    menu_display(curmenu.current_menu = top_menu); /* display the initial menu */
  137.    menu_select(curmenu.current_selection = 0);    /* select the first option */
  138.    menu_prompt(curmenu.current_selection);        /* display selections prompt */
  139. }
  140.  
  141.  
  142. /******************************************************************************
  143.  **                   M E N U _ A D V A N C E                                **
  144.  *****************************************************************************/
  145.  
  146. void ALTCALL
  147. menu_advance() {       /* advance the menu selection pointer */
  148.  
  149.    menu_deselect(curmenu.current_selection);    /* deselect previous entry */
  150.  
  151.    /* change the current selection to the next one or wrap around to 0 */
  152.  
  153.    curmenu.current_selection = (curmenu.current_selection <
  154.                                curmenu.number_selections - 1) ?
  155.                                curmenu.current_selection + 1 : 0;
  156.  
  157.    menu_select(curmenu.current_selection);      /* highlight it */
  158.    menu_prompt(curmenu.current_selection);      /* display its prompt */
  159. }
  160.  
  161.  
  162. /******************************************************************************
  163.  **                   M E N U _ B A C K U P                                  **
  164.  *****************************************************************************/
  165.  
  166. void ALTCALL
  167. menu_backup() {        /* backup the menu selection pointer */
  168.  
  169.    menu_deselect(curmenu.current_selection);    /* deselect previous entry */
  170.  
  171.    /* change the current selection to the previous or warp around to last */
  172.  
  173.    curmenu.current_selection = (curmenu.current_selection > 0) ?
  174.                                curmenu.current_selection - 1 :
  175.                                curmenu.number_selections - 1;
  176.  
  177.    menu_select(curmenu.current_selection);      /* highlight it */
  178.    menu_prompt(curmenu.current_selection);      /* display its prompt */
  179. }
  180.  
  181.  
  182. /******************************************************************************
  183.  **                    M E N U _ D O _ C H A R                               **
  184.  *****************************************************************************/
  185.  
  186. int ALTCALL
  187. menu_do_char(ch)       /* do the menu selection that starts with ch */
  188. int ch;
  189. {
  190.    register int i;
  191.  
  192.    for (i = 0; i < curmenu.number_selections; i++)
  193.       if (toupper(*curmenu.current_menu[i].choice) == toupper(ch)) {
  194.          if (i != curmenu.current_selection &&
  195.              curmenu.current_menu[i].func != NULL) {
  196.             menu_deselect(curmenu.current_selection);
  197.             menu_select(curmenu.current_selection = i);
  198.             menu_prompt(curmenu.current_selection);
  199.          }
  200.          do_selection(i);
  201.          return(1);
  202.       }
  203.    return(0);
  204. }
  205.  
  206. /******************************************************************************
  207.  **                    M E N U _ D O _ C U R R E N T                         **
  208.  *****************************************************************************/
  209.  
  210. void ALTCALL
  211. menu_do_current() {    /* do the current menu selection */
  212.  
  213.    do_selection(curmenu.current_selection);
  214. }
  215.  
  216.  
  217. /******************************************************************************
  218.  **                      D O _ S E L E C T I O N                             **
  219.  *****************************************************************************/
  220.  
  221. static int
  222. do_selection(sel)      /* execute a menu selection */
  223. register int sel;
  224. {
  225.    if (curmenu.current_menu[sel].func != NULL)  /* run function if there is 1 */
  226.       (*curmenu.current_menu[sel].func)();
  227.  
  228.    if (!force_selection) {     /* function can force menu not to update */
  229.  
  230.       /* switch to the specified sub menu or top menu if no sub */
  231.  
  232.       if (curmenu.current_menu[sel].sub_menu != NULL)
  233.          curmenu.current_menu = curmenu.current_menu[sel].sub_menu;
  234.       else
  235.          curmenu.current_menu = top_menu;
  236.  
  237.       menu_display(curmenu.current_menu);          /* display menu */
  238.       menu_select(curmenu.current_selection = 0);  /* select item */
  239.       menu_prompt(curmenu.current_selection);      /* display prompt */
  240.  
  241.    } else                              /* menu was forced */
  242.  
  243.       force_selection = FALSE;         /* only good for one shot */
  244. }
  245.